package cube.data.util;

import java.util.Random;

import cube.utils.StringUtil;

/**
 * 字节数组处理工具
 * 
 * @author abiao
 */
public abstract class DataUtil {

	/**
	 * 小写十六进制字符
	 */
	public static final String lowerHexes = "0123456789abcdef";

	/**
	 * 大写十六进制字符
	 */
	public static final String upperHexes = "0123456789ABCDEF";

	/**
	 * 二进制字符
	 */
	public static final String[] bins = { "0000", "0001", "0010", "0011",
			"0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011",
			"1100", "1101", "1110", "1111" };

	/**
	 * 字母集合
	 */
	public static final char[] letters = { 'a', 'b', 'c', 'd', 'e', 'f', 'g',
			'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
			'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
			'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
			'U', 'V', 'W', 'X', 'Y', 'Z' };

	/**
	 * 字节长度
	 */
	public static final int BYTE_LEN = 1;

	/**
	 * 短整型字节长度
	 */
	public static final int SHORT_LEN = 2;

	/**
	 * 整型字节长度
	 */
	public static final int INT_LEN = 4;

	/**
	 * 长整型字节长度
	 */
	public static final int LONG_LEN = 8;

	/**
	 * 随机数生成器
	 */
	private static final Random ran = new Random();

	/**
	 * 连接多个byte数组
	 * 
	 * @param bs
	 *            数组
	 * @return 连接后数组
	 */
	public static byte[] concat(byte[]... bs) {
		byte[] bytes = new byte[getByteArraysLen(bs)];
		int p = 0;
		for (int i = 0; i < bs.length; i++) {
			System.arraycopy(bs[i], 0, bytes, p, bs[i].length);
			p += bs[i].length;
		}
		return bytes;
	}

	/**
	 * 连接byte或byte数组
	 */
	public static byte[] concat(Object... bs) {
		byte[][] bss = new byte[bs.length][];
		for (int i = 0; i < bss.length; i++) {
			if (bs[i] instanceof Byte) {
				bss[i] = new byte[] { (Byte) bs[i] };
			}
			if (bs[i] instanceof byte[]) {
				bss[i] = (byte[]) bs[i];
			}
		}
		return DataUtil.concat(bss);
	}

	/**
	 * 计算字节数组总长度
	 */
	public static int getByteArraysLen(byte[]... bs) {
		int len = 0;
		for (int i = 0; i < bs.length; i++) {
			len += bs[i].length;
		}
		return len;
	}

	/**
	 * byte转为二进制字符
	 */
	public static String byte2bin(byte b) {
		StringBuffer bin = new StringBuffer();
		for (int i = 0; i < 8; i++) {
			bin.insert(0, b >> i & 0x01);
		}
		return bin.toString();
	}

	/**
	 * 二进制转byte
	 */
	public static byte bin2byte(String bin) {
		return (byte) bin2int(bin);
	}

	/**
	 * 十六进制字符转为二进制字符串
	 */
	public static String hex2bin(char hex) {
		return bins[hex2byte(hex)];
	}

	/**
	 * byte转为小写十六进制字符
	 */
	public static String byte2LowerCaseHex(byte b) {
		return byte2Hex(b, lowerHexes);
	}

	/**
	 * byte转为大写十六进制字符
	 */
	public static String byte2UpperCaseHex(byte b) {
		return byte2Hex(b, upperHexes);
	}

	/**
	 * 获取字节高4位
	 */
	public static char getHighHex(byte b) {
		return byte2LowerCaseHex(b).charAt(0);
	}

	/**
	 * 获取字节低4位
	 */
	public static char getLowHex(byte b) {
		return byte2LowerCaseHex(b).charAt(1);
	}

	/**
	 * 获取char字符的高位字节
	 */
	public static String getHighHex(char c) {
		return DataUtil.byte2LowerCaseHex((byte) (c >> 8 & 0xff));
	}

	/**
	 * 获取char字符的低位字节
	 */
	public static String getLowHex(char c) {
		return DataUtil.byte2LowerCaseHex((byte) (c & 0xff));
	}

	/**
	 * byte转为十六进制字符
	 */
	private static String byte2Hex(byte b, String hexStr) {
		return ("" + hexStr.charAt(0xf & b >> 4) + hexStr.charAt(b & 0xf));
	}

	/**
	 * char转byte数组
	 * 
	 * @param c
	 *            char
	 * @return byte
	 */
	public static byte[] char2bytes(char c) {
		byte[] bs = new byte[2];
		bs[0] = (byte) ((c & 0xff00) >> 8);
		bs[1] = (byte) (c & 0x00ff);
		return bs;
	}

	/**
	 * 批量转换int值为byte值
	 */
	public static byte[] ints2bytes(int... ints) {
		byte[] bytes = new byte[ints.length];
		for (int i = 0; i < bytes.length; i++) {
			bytes[i] = (byte) ints[i];
		}
		return bytes;
	}

	/**
	 * 十六进制字符转为整型值
	 */
	public static int hex2int(char hex) {
		return Integer.parseInt(String.valueOf(hex), 16);
	}

	/**
	 * 二进制字符串转为整型值
	 */
	public static int bin2int(String bin) {
		return Integer.parseInt(bin, 2);
	}

	/**
	 * 十六进制字符串转byte
	 */
	public static byte hex2byte(String hex) {
		return (byte) Integer.parseInt(hex, 16);
	}

	/**
	 * 十六进制字符转byte
	 */
	public static byte hex2byte(char hex) {
		return hex2byte(String.valueOf(hex));
	}

	/**
	 * copy指定位置字节
	 */
	public static byte[] copy(byte[] data, int begin, int end) {
		byte[] copy = new byte[end - begin];
		System.arraycopy(data, begin, copy, 0, copy.length);
		return copy;
	}

	/**
	 * 复制字节数组开头字节
	 */
	public static byte[] copyhead(byte[] data, int size) {
		return copy(data, 0, size);
	}

	/**
	 * 复制字节数组末尾字节
	 */
	public static byte[] copytail(byte[] data, int size) {
		return copy(data, data.length - size, data.length);
	}

	/**
	 * 反转字节序
	 */
	public static byte[] reverse(byte[] data) {
		byte[] reverse = new byte[data.length];
		for (int i = 0; i < reverse.length; i++) {
			reverse[i] = data[data.length - i - 1];
		}
		return reverse;
	}

	/**
	 * 数组清零
	 */
	public static void reset(byte[] b) {
		System.arraycopy(new byte[b.length], 0, b, 0, b.length);
	}

	/**
	 * 4字节byte数组转为int
	 */
	public static int bytes2int(byte[] bs) {
		int len = min(bs.length, INT_LEN);
		int v = 0;
		for (int i = 0; i < len; i++) {
			v += (bs[len - i - 1] & 0xff) << (8 * i);
		}
		return v;
	}

	/**
	 * 1个int值转为4字节byte数组
	 */
	public static byte[] int2bytes(int v) {
		byte[] bs = new byte[INT_LEN];
		for (int i = 0; i < bs.length; i++) {
			bs[bs.length - i - 1] = (byte) (v >> (i * 8));
		}
		return bs;
	}

	/**
	 * byte数组转short
	 */
	public static short bytes2short(byte[] bs) {
		int len = min(bs.length, SHORT_LEN);
		short v = 0;
		for (int i = 0; i < len; i++) {
			v += (bs[len - i - 1] & 0xff) << (8 * i);
		}
		return v;
	}

	/**
	 * short转byte数组
	 */
	public static byte[] short2bytes(short v) {
		byte[] bs = new byte[SHORT_LEN];
		for (int i = 0; i < bs.length; i++) {
			bs[bs.length - i - 1] = (byte) (v >> (i * 8));
		}
		return bs;
	}

	/**
	 * long转byte数组
	 */
	public static byte[] long2bytes(long v) {
		byte[] bs = new byte[LONG_LEN];
		for (int i = 0; i < bs.length; i++) {
			bs[bs.length - 1 - i] = (byte) (v >> (i * 8));
		}
		return bs;
	}

	/**
	 * byte数组转long
	 */
	public static long bytes2long(byte[] bs) {
		long v = 0;
		int len = min(bs.length, LONG_LEN);
		for (int i = 0; i < len; i++) {
			v += (bs[len - i - 1] & 0xff) << (8 * i);
		}
		return v;
	}

	/**
	 * short值移位为int值
	 */
	public static int short2int(short s) {
		return s & 0xffff;
	}

	/**
	 * 求最小值
	 */
	public static int min(int x, int y) {
		return x < y ? x : y;
	}

	/**
	 * 求最大值
	 */
	public static int max(int x, int y) {
		return x > y ? x : y;
	}

	/**
	 * 设置比特位
	 */
	public static byte setBit(byte b, int pos, int bit) {
		if (bit == 1) {
			b |= (1 << (8 - pos));
		}
		if (bit == 0) {
			b &= ~(1 << (8 - pos));
		}
		return b;
	}

	/**
	 * 获取比特位, pos的范围为[1, 8]
	 */
	public static int getBit(byte b, int pos) {
		return b >> (8 - pos) & 0x01;
	}

	/**
	 * 字符串转为整型值
	 */
	public static int toInt(String s) {
		return Integer.parseInt(s);
	}

	/**
	 * 字符串转为长整型值
	 */
	public static long toLong(String s) {
		return Long.parseLong(s);
	}

	/**
	 * 字符串转为双精度值
	 */
	public static double toDouble(String s) {
		return Double.parseDouble(s);
	}

	/**
	 * 数值对象转为长整型值
	 */
	public static long toLong(Object num) {
		return toLong(num.toString());
	}

	/**
	 * 是否为奇数
	 */
	public static boolean isOdd(int i) {
		return i % 2 == 1;
	}

	/**
	 * 是否为偶数
	 */
	public static boolean isEven(int i) {
		return i % 2 == 0;
	}

	/**
	 * 比较两个不同类型的数的数值是否一样
	 */
	public static boolean numEquals(Object num1, Object num2) {
		if (num1 == null || num2 == null) {
			return false;
		}
		return num1.toString().equals(num2.toString());
	}

	/**
	 * 返回指定范围的随机数一枚
	 */
	public static int random(int begin, int end) {
		return ran.nextInt(end - begin) + begin;
	}

	/**
	 * 返回指定范围的长整型随机值
	 */
	public static long random(long begin, long end) {
		return Math.abs(ran.nextLong()) % (end - begin) + begin;
	}

	/**
	 * 获取指定长度的随机数
	 */
	public static String getRandomNum(int length) {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < length; i++) {
			sb.append(random(0, 10));
		}
		return sb.toString();
	}

	/**
	 * 获取指定长度的随机字符
	 */
	public static String getRandomChar(int length) {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < length; i++) {
			sb.append((char) random(32, 127));
		}
		return sb.toString();
	}

	/**
	 * 获取指定长度的随机字母
	 */
	public static String getRandomLetter(int length) {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < length; i++) {
			sb.append(letters[random(0, letters.length)]);
		}
		return sb.toString();
	}

	/**
	 * 计算整型值位数
	 */
	public static int length(int i) {
		if (i == 0) {
			return 1;
		}
		int length = 0;
		while (i != 0) {
			i /= 10;
			length++;
		}
		return length;
	}

	/**
	 * 交换位置
	 */
	public static void swap(int x[], int a, int b) {
		int t = x[a];
		x[a] = x[b];
		x[b] = t;
	}

	/**
	 * 整型字符串转为对应int值数组
	 */
	public static byte[] intNums2Bytes(String intNums) {
		byte[] bs = new byte[intNums.length()];
		for (int i = 0; i < bs.length; i++) {
			bs[i] = (byte) toInt(intNums.charAt(i) + "");
		}
		return bs;
	}

	/**
	 * 保留precision位小数
	 */
	public static double getDouble(double d, int precision) {
		int aux = (int) Math.pow(10, precision);
		return (double) (int) (d * aux) / aux;
	}

	/**
	 * 四舍五入保留precision位小数
	 */
	public static double round(double d, int precision) {
		int aux = (int) Math.pow(10, precision);
		return (double) Math.round(d * aux) / aux;
	}

	/**
	 * 异或运算
	 */
	public static void xor(byte[] data, int b) {
		for (int i = 0; i < data.length; i++) {
			data[i] ^= b;
		}
	}

	/**
	 * byte数组转为小写十六进制字符串
	 */
	public static String toHexString(byte[] bs) {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < bs.length; i++) {
			sb.append(byte2LowerCaseHex(bs[i]));
		}
		return sb.toString();
	}

	/**
	 * 连续十六进制字符串转为字节数组
	 */
	public static byte[] toBytes(String hexes) {
		String hexs = StringUtil.deleteWhiteSpace(hexes);
		byte[] data = new byte[hexs.length() / 2];
		for (int i = 0; i < data.length; i++) {
			data[i] = DataUtil.hex2byte(hexs.substring(2 * i, 2 * i + 2));
		}
		return data;
	}
}
